local assets =
{
    Asset( "IMAGE", "images/inventoryimages/npc_item_cards_station.tex" ),  -- 背包贴图
    Asset( "ATLAS", "images/inventoryimages/npc_item_cards_station.xml" ),

}

local function GetStringsTable()
    return TUNING.NPC_CHAT_TABLE[ type(TUNING.__NPC_LANGUAGE)=="function" and TUNING.__NPC_LANGUAGE() or TUNING.__NPC_LANGUAGE ] ["npc_item_cards_station"] or {}
end


local function table_fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
	inst.entity:AddNetwork()

    inst.entity:AddAnimState()
    inst.AnimState:SetBank("carnival_prizebooth")
    inst.AnimState:SetBuild("carnival_prizebooth")
    
    inst.AnimState:PlayAnimation("place")
    inst.AnimState:PushAnimation("idle")
    local hide_symbol = {"awning","sign","dark","flag_parts","flagpole","inside","inside lights","pillars"}
    for k, v in pairs(hide_symbol) do
        inst.AnimState:HideSymbol(v)
    end

    -- MakeObstaclePhysics(inst, 1.5)
    -- inst:AddTag("npc_item_cards_station")
    inst:AddTag("INLIMBO")
    inst:AddTag("FX")
    inst:AddTag("NOCLICK")

    if not TheWorld.ismastersim then
        return inst
    end

    return inst
end

local function item_accept_test(inst,item)
    if item and item.prefab == "npc_item_goldnugget_coin" then
        return true
    end
    return false
end
local function OnGetItem(inst, giver, item)
    if giver then
        if giver:HasTag("npc_cards_sys.ready") and giver.components.npc_cards_sys then
            giver.components.npc_cards_sys:Start()
        else
            giver.npc_base_lib:GiveItemByName("npc_item_goldnugget_coin",1)
        end    
    end
end

local function npc_fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
	inst.entity:AddNetwork()
    inst.entity:AddSoundEmitter()
    inst.entity:AddMiniMapEntity()

    inst.MiniMapEntity:SetPriority(5)
    inst.MiniMapEntity:SetIcon("npc_item_cards_station.tex")

    inst.entity:AddAnimState()
    inst.AnimState:SetBank("walrus")
    inst.AnimState:SetBuild("walrus_build")

    inst.Transform:SetFourFaced()
    inst.AnimState:PlayAnimation("idle_loop",true)


    local scale = 1.5
    inst.AnimState:SetScale(scale, scale, scale)

    MakeObstaclePhysics(inst, 1.5)
    inst:AddTag("npc_item_cards_station")

    inst.talk_sound = "dontstarve/creatures/mctusk/taunt"
    inst.entity:SetPristine()

    ----------------------------------------------------------------------------------------------------
    ------- 让海象正面一直面对摄像机
        if not TheNet:IsDedicated() then        --- 只在client 执行
            local function Face2Camera()
                local player =  ThePlayer or  GetPlayer()
                if inst:IsNearPlayer(30) and TheCamera and player and not player:HasTag("playerghost") then
                        inst.replica.npc_base_lib:PushEvent("face",{
                            pt = TheCamera:GetDownVec(),
                            userid = player.userid
                        })                    
                end
            end
            inst:DoTaskInTime(0,Face2Camera)
            inst:DoPeriodicTask(5,function()
                Face2Camera()
            end)
        end
        if TheWorld.ismastersim then
            inst:ListenForEvent("face",function(_,_table)
                if _table and _table.pt and _table.userid then
                    local player = inst:GetNearestPlayer(true)
                    if player  and player.userid == _table.userid then
                        local pt = Vector3(inst.Transform:GetWorldPosition())
                        local pt2 = _table.pt
                        inst:FacePoint(pt.x+pt2.x,0,pt.z+pt2.z)
                    end
                end
            end)
        end

    ----------------------------------------------------------------------------------------------------
    inst:ListenForEvent("RPC_Remove",inst.Remove)
    ----------------------------------------------------------------------------------------------------
    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("npc_base_lib")
    inst:AddComponent("npc_everything_data")
    inst:DoTaskInTime(0.1,function()
        local theTable = inst:SpawnChild("npc_item_cards_station_table")
        inst.AnimState:HideSymbol("pig_leg")
        theTable.AnimState:SetFinalOffset(10)
        inst.AnimState:SetFinalOffset(0)
    end)

    inst:AddComponent("inspectable") --可检查组件
    
    inst:AddComponent("named")
    inst.components.named:SetName(GetStringsTable().name)
    STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_cards_station")] = GetStringsTable().inspect_str  --人物检查的描述

    ------------------------------------------------------------------------------------------------------------
    inst:AddComponent("playerprox")
        inst.components.playerprox:SetDist(6, 10)
        inst.components.playerprox:SetOnPlayerNear(function()
            inst.npc_base_lib:Show_Chat_Bubble({
                image = "npc_item_goldnugget_coin" , -- prefab name
                height = 4
            })
            inst:DoTaskInTime(10,function()
                inst.npc_base_lib:Hide_Chat_Bubble()
            end)
        end)
        inst.components.playerprox:SetOnPlayerFar(function()
            inst.npc_base_lib:Hide_Chat_Bubble()        
        end)
    ------------------------------------------------------------------------------------------------------------
    inst:AddComponent("trader")
        inst.components.trader:SetAcceptTest(item_accept_test)
        inst.components.trader.onaccept = OnGetItem
        inst.components.trader.deleteitemonaccept = true
        inst.components.trader:SetAbleToAcceptTest(item_accept_test)

    ------------------------------------------------------------------------------------------------------------
    inst:AddComponent("workable")   ----- 只能由玩家锤掉，外部冲撞一类的无法摧毁
        inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
        inst.components.workable:SetWorkLeft(4)        
        inst.components.workable:SetOnWorkCallback(function(inst,worker)
            if worker and worker:HasTag("player") then
                if inst.___work_tag_task then
                    inst.___work_tag_task:Cancel()
                end
                inst:AddTag("player_on_work")
                inst.___work_tag_task = inst:DoTaskInTime(3,function()
                    inst:RemoveTag("player_on_work")
                end)
            end
        end)
        inst.components.workable:SetOnFinishCallback(function(inst,worker)
            if worker and worker:HasTag("player") and inst:HasTag("player_on_work") then
                local pt = Vector3(inst.Transform:GetWorldPosition())
                inst.npc_base_lib:RPC_PushEvent("RPC_Remove")
                inst:Remove()
                local monster = SpawnPrefab("walrus")
                monster:AddTag("npc_task")
                monster.Transform:SetPosition(pt.x, 0, pt.z)
                SpawnPrefab("collapse_big").Transform:SetPosition(pt.x,0,pt.z)  --- 烟雾
                worker.npc_base_lib:Throw_Out_Items({
                    target = pt,
                    name = "npc_item_goldnugget_coin",
                    num = 5,    
                    range = 5,
                    height = 5,
                    random_height = true
                })
            end
        end)
        inst.components.workable.Destroy_old = inst.components.workable.Destroy
        inst.components.workable.Destroy = function(self,destroyer)
            if self.inst:HasTag("player_on_work") then
                self:Destroy_old()
            else
                -- print("info: Destroy false")
            end
        end
    ------------------------------------------------------------------------------------------------------------
    ------- 一个世界只能摆放一个
        local old = TheSim:FindFirstEntityWithTag("npc_item_cards_station")
        if old and old:IsValid() and old ~= inst then
            old:Remove()
            inst:DoTaskInTime(0,function()
                local player = inst:GetNearestPlayer()
                if player and player.npc_base_lib then
                    player.npc_base_lib:GiveItemByName("npc_item_goldnugget_coin",5)
                end
            end)
        end
    ------------------------------------------------------------------------------------------------------------
    return inst
end

local function placer_postinit_fn(inst)
    local hide_symbol = {"awning","sign","dark","flag_parts","flagpole","inside","inside lights","pillars"}
    for k, v in pairs(hide_symbol) do
        inst.AnimState:HideSymbol(v)
    end
end

local function GetSurroundPoints(CMD_TABLE)
    -- local CMD_TABLE = {
    --     target = inst or Vector3(),
    --     range = 8,
    --     num = 8
    -- }
    if CMD_TABLE == nil then
        return
    end
    local theMid = nil
    if CMD_TABLE.target == nil then
        theMid = Vector3( self.inst.Transform:GetWorldPosition() )
    elseif CMD_TABLE.target.x then
        theMid = CMD_TABLE.target
    elseif CMD_TABLE.target.prefab then
        theMid = Vector3( CMD_TABLE.target.Transform:GetWorldPosition() )
    else
        return
    end
    -- --------------------------------------------------------------------------------------------------------------------
    -- -- 8 points
    -- local retPoints = {}
    -- for i = 1, 8, 1 do
    --     local tempDeg = (PI/4)*(i-1)
    --     local tempPoint = theMidPoint + Vector3( Range*math.cos(tempDeg) ,  0  ,  Range*math.sin(tempDeg)    )
    --     table.insert(retPoints,tempPoint)
    -- end
    -- --------------------------------------------------------------------------------------------------------------------
    local num = CMD_TABLE.num or 8
    local range = CMD_TABLE.range or 8
    local retPoints = {}
    for i = 1, num, 1 do
        local tempDeg = (2*PI/num)*(i-1)
        local tempPoint = theMid + Vector3( range*math.cos(tempDeg) ,  0  ,  range*math.sin(tempDeg)    )
        table.insert(retPoints,tempPoint)
    end

    return retPoints
end

local deployable_data = ------ 放置物品的inst的创建,MakeDeployableKitItem 调用的 fn
{
	deploymode = DEPLOYMODE.CUSTOM,
	custom_candeploy_fn = function(inst, pt, mouseover, deployer)   --- 放置时候的检查fn
        if inst.anim_change_flag ~= true then
            inst.anim_change_flag = true
            placer_postinit_fn(inst)
        end
        -- if TheWorld:HasTag("cave") then
        --     return false
        -- end

        if TheWorld.Map:IsOceanAtPoint(pt.x, pt.y, pt.z,true) then
            return false
        end

        local points = GetSurroundPoints({
            target = pt,
            num = 6,
            range = 6
        })
        table.insert(points,pt)
        for k, temp_pt in pairs(points) do
            if TheWorld.Map:IsOceanAtPoint(temp_pt.x, temp_pt.y, temp_pt.z,true) == true or TheWorld.Map:IsAboveGroundAtPoint(temp_pt.x, temp_pt.y, temp_pt.z) ~= true then
                return false
            end                
        end

        return true
    end,

    master_postinit = function(inst)

        -- inst:AddComponent("npc_base_lib")
        -- inst:AddComponent("npc_everything_data")
        if inst.anim_change_flag ~= true then
            inst.anim_change_flag = true
            placer_postinit_fn(inst)
        end

        -- inst.components.inventoryitem:ChangeImageName("npc_item_cards_station") --- 设置物品在背包里的贴图
        inst.components.inventoryitem.imagename = "npc_item_cards_station"
        inst.components.inventoryitem.atlasname = "images/inventoryimages/npc_item_cards_station.xml"

        inst:AddComponent("named")
        inst.components.named:SetName(GetStringsTable().name)
        STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_cards_station_kit")] = GetStringsTable().inspect_str  --人物检查的描述
    

        local function onburnt_fn(inst)
            local player = inst:GetNearestPlayer()
            if player and player.npc_base_lib then
                player.npc_base_lib:GiveItemByName("npc_item_goldnugget_coin",4)
            end
        end
        inst:ListenForEvent("fueltaken",onburnt_fn)
        inst:ListenForEvent("onburnt",onburnt_fn)
    
    end,
}

return Prefab("npc_item_cards_station",npc_fn),
        Prefab("npc_item_cards_station_table",table_fn),
        MakePlacer("npc_item_cards_station_kit_placer", "carnival_prizebooth", "carnival_prizebooth", "idle",nil, nil, nil, nil, nil, nil, placer_postinit_fn),
        MakeDeployableKitItem("npc_item_cards_station_kit", "npc_item_cards_station", "carnival_prizebooth", "carnival_prizebooth", "idle", assets, {size = "med", scale = 0.77}, nil, {fuelvalue = TUNING.LARGE_FUEL}, deployable_data)